import logging
from datetime import datetime
from uuid import uuid4

import requests
from typing import List, Optional

from langchain_community.document_loaders import PyPDFLoader
from langchain_community.vectorstores import Milvus, Zilliz
from langchain_core.embeddings import Embeddings
from langchain_core.vectorstores import VectorStore
from langchain_text_splitters import RecursiveCharacterTextSplitter

from config.core.aigc import MILVUS_CONNECTION_ARGS
from core.exception import CustomException
from crewplus.apps.rag.processors.base_processor import DocumentProcessor
from crewplus.apps.rag.schemas.ingest_request import IngestRequest
from crewplus.apps.rag.schemas.document import Document
from crewplus.apps.rag.schemas.ingest_status import IngestStatus
from crewplus.apps.rag.utils.document_util import unify_documents_meta
from crewplus.services.vdb_service import VDBService


class SharepointDocumentProcessor():
    def __init__(self, client_id: str, client_secret: str, tenant_id: str):
        self.base_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
        self.resource_url = "https://graph.microsoft.com/v1.0/drive/root/children"
        self.client_id = client_id
        self.client_secret = client_secret
        self.token = None

    def authenticate(self):
        """Authenticate with SharePoint and retrieve access token."""
        payload = {
            'client_id': self.client_id,
            'scope': 'https://graph.microsoft.com/.default',
            'client_secret': self.client_secret,
            'grant_type': 'client_credentials'
        }
        headers = {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        response = requests.post(self.base_url, data=payload, headers=headers)
        response_data = response.json()
        self.token = response_data.get('access_token')

    # def get_documents(self) -> List[Document]:
    #     """Retrieve documents from SharePoint."""
    #     if not self.token:
    #         self.authenticate()
    #     headers = {
    #         'Authorization': f'Bearer {self.token}'
    #     }
    #     response = requests.get(self.resource_url, headers=headers)
    #     documents_data = response.json().get('value', [])
    #     documents = []
    #
    #     for doc_data in documents_data:
    #         mime_type = doc_data.get('file', {}).get('mimeType', '')
    #         if mime_type == 'application/pdf':
    #             file_type = 'pdf'
    #         elif mime_type.startswith('image/'):
    #             file_type = 'image'
    #         else:
    #             file_type = 'unknown'  # 或者其他默认类型
    #         print(f"file_type:{file_type}")
    #         if file_type == 'unknown':
    #             continue
    #         else:
    #             document = Document(
    #                 source_url=doc_data.get('@microsoft.graph.downloadUrl'),
    #                 # source_url=doc_data.get('webUrl'),
    #                 title=doc_data.get('name'),
    #                 source_type='sharepoint',
    #                 file_type=file_type,
    #                 content=doc_data.get('webUrl'),
    #                 metadata=doc_data
    #             )
    #             documents.append(document)
    #     return documents
    def get_documents(self) -> List[Document]:
        """Retrieve documents from SharePoint."""
        if not self.token:
            self.authenticate()
        headers = {
            'Authorization': f'Bearer {self.token}'
        }
        documents = []
        self._retrieve_documents(self.resource_url, headers, documents)
        return documents

    def _retrieve_documents(self, url: str, headers: dict, documents: List[Document]):
        """Helper function to recursively retrieve documents."""
        response = requests.get(url, headers=headers)
        documents_data = response.json().get('value', [])
        for doc_data in documents_data:
            if 'folder' in doc_data:
                # If it's a folder, recursively retrieve its contents
                drive_id = doc_data['parentReference']['driveId']
                item_id = doc_data['id']
                folder_url = f"https://graph.microsoft.com/v1.0/drives/{drive_id}/items/{item_id}/children"
                self._retrieve_documents(folder_url, headers, documents)
            else:
                # Process file
                mime_type = doc_data.get('file', {}).get('mimeType', '')
                logging.info("mime_type:" + mime_type)
                if mime_type == 'application/pdf':
                    file_type = 'pdf'
                elif mime_type == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
                    file_type = 'doc'
                elif mime_type == 'application/vnd.ms-powerpoint':
                    file_type = 'ppt'
                elif mime_type == 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
                    file_type = 'ppt'
                elif mime_type == 'application/vnd.ms-excel':
                    file_type = 'excel'
                elif mime_type == 'text/plain':
                    file_type = 'txt'
                elif mime_type == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
                    file_type = 'excel'
                # elif mime_type == 'application/rtf':
                #     file_type = 'rtf'
                elif mime_type.startswith('image/'):
                    file_type = 'image'
                else:
                    file_type = 'unknown'  # 或者其他默认类型

                if file_type == 'unknown':
                    continue
                else:
                    document = Document(
                        download_url=doc_data.get('@microsoft.graph.downloadUrl'),
                        title=doc_data.get('name'),
                        source_type='sharepoint',
                        file_type=file_type,
                        content=doc_data.get('webUrl'),
                        source_url=doc_data.get('webUrl'),
                        metadata=doc_data
                    )
                    documents.append(document)
